# 小案例看看pca怎么使用
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.decomposition import PCA

iris = load_iris()
datas = iris.data
# 直接指定降到几维
# pca = PCA(n_components=2)
# result = pca.fit_transform(datas)

# 不指定n_components 则可以看出不同维度的方差贡献率
# pca = PCA()
# result = pca.fit_transform(datas)
#
# print(result.shape)
# print(pca.explained_variance_)
# print(pca.explained_variance_ratio_)
#
# import numpy as np
#
# plt.plot([1, 2, 3, 4], np.cumsum(pca.explained_variance_ratio_))
# plt.xticks(([1, 2, 3, 4]))
# plt.xlabel("不同纬度")
# plt.ylabel("方差贡献率")
# plt.show()

# # 最大似然数
# pca = PCA(n_components="mle")
# result = pca.fit_transform(datas)
# # 自行选择了三个特征，缺点：维度高的时候性能差
# print(result.shape)


# # 按信息量占比选择维度
# # svd_solver 奇异值分解器可以不计算协方差矩阵等复杂的矩阵计算，直接求出新特征控件和降为后的特征矩阵
# # 总的来说就是用svd简化计算过程，而后使用pca进行降维
# # svd_solver参数：auto（默认）、full、arpack、randomized。 一般使用默认的，而后试试randomized
# pca = PCA(n_components=0.97, svd_solver="full")
# result = pca.fit_transform(datas)
# print(result.shape)

# _________________人脸数据查看降维后的特征保留程度_________________

from sklearn.datasets import fetch_lfw_people

peoples = fetch_lfw_people(min_faces_per_person=60)
print(peoples.data.shape)
print(peoples.images.shape)

x = peoples.data

fig, axes = plt.subplots(4, 5, figsize=(8, 4), subplot_kw={"xticks": [], "yticks": []})

for i, ax in enumerate(axes.flat):
    ax.imshow(peoples.images[i, :, :], cmap="gray")

# # 降维成150个维度
# pca = PCA(150).fit(x)
# v = pca.components_
# print(v.shape)
# fig, axes = plt.subplots(4, 5, figsize=(8, 4), subplot_kw={"xticks": [], "yticks": []})
#
# for i, ax in enumerate(axes.flat):
#     ax.imshow(v[i, :].reshape(62, 47), cmap="gray")
# plt.show()
#

# 使用inverse返回原空间，发现图片丢失了一些细节，并不能完全复原。降维不是完全可逆的。
pca = PCA(150)
result = pca.fit_transform(x)
transform = pca.inverse_transform(result)
print(transform.shape)

fig, axes = plt.subplots(4, 5, figsize=(8, 4), subplot_kw={"xticks": [], "yticks": []})

for i, ax in enumerate(axes.flat):
    ax.imshow(transform[i, :].reshape(62, 47), cmap="gray")

plt.show()
